/**
 * @file nglogger.h
 * @author Suk Robert Koh (srkoh87z@gmail.com)
 *
 * @brief NGLogger class handles logging information
 */

#ifndef NGLOGGER_H_
#define NGLOGGER_H_

#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#define LOG_LEVEL_NO_LOG	0		/** log level for no logging */
#define LOG_LEVEL_ERROR		1		/** log level for error messages */
#define LOG_LEVEL_WARN		2		/** log level for warning messages */
#define LOG_LEVEL_INFO		3		/** log level for info messages */
#define LOG_LEVEL_DEBUG		4		/** log level for debug messages */

/**
 * @class	NGLogger	Static singleton class for logging information
 *
 * TODO: support other methods of logging besides STDOUT i.e., to file, e-mail
 * TODO: implement timestamp when printing
 */
class NGLogger
{
private:
	/**
	 * Constructor for NGLogger class
	 */
	NGLogger() {}
	/**
	 * Destructor for NGLogger class
	 */
	~NGLogger() {}

public:
	/**
	 * Logs a debug statement
	 *
	 * @param	A debug statement to log
	 */
	static void debug(const char *lpszFmt, ...)
	{
#ifdef DEBUG
		int logLevel = LOG_LEVEL_DEBUG;
#else
		int logLevel = LOG_LEVEL_INFO;
#endif

		// only print if debug level is 3
		if(logLevel >= LOG_LEVEL_DEBUG)
		{
			char output[256];
			va_list Vargs;

			va_start(Vargs, lpszFmt);
			vsprintf(output, lpszFmt, Vargs);
			va_end(Vargs);
			strcat(output, "\n");

			printf("[DEBUG] %s", output);
		}
	}

	/**
	 * Logs an information statement
	 *
	 * @param	An information statement to log
	 */
	static void info(const char *lpszFmt, ...)
	{
#ifdef DEBUG
		int logLevel = LOG_LEVEL_DEBUG;
#else
		int logLevel = LOG_LEVEL_INFO;
#endif

		// only print if log level is 2
		if(logLevel >= LOG_LEVEL_INFO)
		{
			char output[256];
			va_list Vargs;

			va_start(Vargs, lpszFmt);
			vsprintf(output, lpszFmt, Vargs);
			va_end(Vargs);
			strcat(output, "\n");

			printf("[INFO] %s", output);
		}
	}

	/**
	 * Logs an error statement
	 *
	 * @param	A warning statement to log
	 */
	static void warn(const char *lpszFmt, ...)
	{
#ifdef DEBUG
		int logLevel = LOG_LEVEL_DEBUG;
#else
		int logLevel = LOG_LEVEL_INFO;
#endif

		// only print if debug level is 3
		if(logLevel >= LOG_LEVEL_WARN)
		{
			char output[256];
			va_list Vargs;

			va_start(Vargs, lpszFmt);
			vsprintf(output, lpszFmt, Vargs);
			va_end(Vargs);
			strcat(output, "\n");

			printf("[WARN] %s", output);
		}
	}

	/**
	 * Logs an error statement
	 *
	 * @param	An error statement to log
	 */
	static void error(const char *lpszFmt, ...)
	{
#ifdef DEBUG
		int logLevel = LOG_LEVEL_DEBUG;
#else
		int logLevel = LOG_LEVEL_INFO;
#endif

		// only print if debug level is 3
		if(logLevel >= LOG_LEVEL_ERROR)
		{
			char output[256];
			va_list Vargs;

			va_start(Vargs, lpszFmt);
			vsprintf(output, lpszFmt, Vargs);
			va_end(Vargs);
			strcat(output, "\n");

			printf("[ERROR] %s", output);
		}
	}
};

#endif /* NGLOGGER_H_ */
